package orxatas.travelme.activity;

import java.util.ArrayList;
import java.util.List;

import orxatas.travelme.R;
import orxatas.travelme.entity.Group;
import orxatas.travelme.entity.User;
import orxatas.travelme.manager.AccountManager;
import orxatas.travelme.manager.DataManager;
import orxatas.travelme.manager.GroupManager;
import orxatas.travelme.manager.exceptions.GroupNameInvalid;
import orxatas.travelme.sync.AsyncNoticeCode;
import orxatas.travelme.sync.exceptions.ImposibleAcceptInvitation;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.ListActivity;
import android.app.ProgressDialog;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;

public class GroupListActivity extends ListActivity implements AsyncActivity{

	private final static String TAG = "travelme_GroupListActivity";
	private User user;
	private int userID;
	private GroupManager groupManager;
	private AccountManager accountManager;
	private GroupAdapter adapter;
	private ArrayList<Group> groupList;
	private ProgressDialog dialog;
	private Listener listener;
	private boolean listenerRegistered = false;
	
	
	
	@Override
	public void onCreate(Bundle icicle) {
		super.onCreate(icicle);
		this.setContentView(R.layout.group_list);
		
		accountManager = new AccountManager(this);
	    
		if(!accountManager.isLogged()){
			startActivity(new Intent(GroupListActivity.this, LoginActivity.class));
			finish();
		}
		
		groupManager = new GroupManager(this);
		
	    user = accountManager.getUserLogged();
	    
	    groupList = new ArrayList<Group>();
	    
	    if(user != null) {
	    	userID = user.getId();
	    	List<Group> list = groupManager.getGroupList();
		    if(list != null){
		    	groupList = new ArrayList<Group>(list);
		    }
	    }
	    else{
	    	Log.e(TAG, "onCreate - no user logged");
	    	userID = -1;
	    }

		adapter = new GroupAdapter(this,R.layout.group_list_row , groupList);
		setListAdapter(adapter);
		
		listener = new Listener();
		
		if(new DataManager(this).isSync())
			syncStarted();
	}
	
    protected class Listener extends BroadcastReceiver {

        @Override
        public void onReceive(Context context, Intent intent) {
            if (intent.getAction().equals("SYNC_ACTION")) {
            	new DataManager(GroupListActivity.this).syncAll();
            } else if(intent.getAction().equals("SHOW_FRIENDS")){
            	startActivity(new Intent(GroupListActivity.this, FriendListActivity.class));
            }
        }
    }
    
	@Override
    protected void onResume() {
        super.onResume();

        if (!listenerRegistered ) {
            registerReceiver(listener, new IntentFilter("SYNC_ACTION"));
            registerReceiver(listener, new IntentFilter("SHOW_FRIENDS"));
            listenerRegistered = true;
        }
    }

    @Override
    protected void onPause() {
        super.onPause();
        
        if (listenerRegistered) {
            unregisterReceiver(listener);
            listenerRegistered = false;
        }
    }
    
	@Override
	protected void onDestroy() {
		super.onDestroy();
		
		//VERY important.
        new DataManager(this).activityEnds(this);
	}

	public void showProgressDialog(){
		
		if(dialog == null){
			dialog = ProgressDialog.show(GroupListActivity.this, "", 
					getResources().getString(R.string.group_list_progressdialog_text) ,true, false);
		}
		

	}
	
	public void hideProgressDialog(){
		if(dialog != null){
			dialog.dismiss();
			dialog = null;
		}
	}
	
	
	@Override
	protected void onListItemClick(ListView l, View v, int position, long id) {
		Group item = (Group) getListAdapter().getItem(position);
		Intent i = new Intent(GroupListActivity.this, GroupTabActivity.class);
		i.putExtra("id_grupo", item.getIdOffline());
	    i.putExtra("owner_grupo", item.getOwner());
	    i.putExtra("name_grupo", item.getName());
		startActivity(i);
	}
	
	
	@Override
	public boolean onCreateOptionsMenu(Menu menu) { 
	  MenuInflater inflater = getMenuInflater(); 
	  inflater.inflate(R.layout.menu_group_list, menu); 
	  return true; 
	}
	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		switch(item.getItemId()){
		case R.id.menu_group_list_1:
			addNewGroup();
			
			break;
		case R.id.menu_group_list_disconnect:
			accountManager.disconnect();
			startActivity(new Intent(GroupListActivity.this, LoginActivity.class));
			finish();
			
			break;
		default:
			break;
		}
		return super.onOptionsItemSelected(item);
	}
	
	private void addNewGroup(){
		AlertDialog.Builder alert = new AlertDialog.Builder(this);

		
		alert.setTitle(R.string.group_list_new_group_title);
		alert.setMessage(R.string.group_list_new_group_message);
		

		// Set an EditText view to get user input
		final EditText input = new EditText(this);
		alert.setView(input);

		alert.setPositiveButton("Ok", new DialogInterface.OnClickListener() {
		public void onClick(DialogInterface dialog, int whichButton) {
			String value = input.getText().toString();
			try{
				groupManager.addNewGroup(value);
				Log.i(TAG, "new group: "+value);
				reloadGroupList();
				dialog.cancel();
			}catch(GroupNameInvalid gni){
				Toast.makeText(GroupListActivity.this, getResources().getString(R.string.group_list_new_group_invalid_name_message), Toast.LENGTH_LONG).show();
			}
			
			
		  }
		});

		alert.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
			public void onClick(DialogInterface dialog, int whichButton) {
			  dialog.cancel();
		  }
		});

		alert.show();
	}
	
	
	static class ViewHolder  
    {  
    	ImageView image;
        TextView groupNameText;
        TextView groupMembers;
        ImageButton buttonAccept;
        ImageButton buttonReject;
        LinearLayout ll;
    }
	
	private class GroupAdapter extends ArrayAdapter<Group> {

        private ArrayList<Group> items;
        private Group group;
        private LayoutInflater inflater;

        public GroupAdapter(Context context, int textViewResourceId, ArrayList<Group> items) {
                super(context, textViewResourceId, items);
                this.items = items;
                inflater = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        }

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
                ViewHolder holder;
                if (convertView == null) {
                	
                    convertView = inflater.inflate(R.layout.group_list_row, null);
                    
                    holder = new ViewHolder();
                    holder.image = (ImageView) convertView.findViewById(R.id.row_icon);
            		holder.groupNameText = (TextView) convertView.findViewById(R.id.row_group_name);
            		holder.groupMembers = (TextView) convertView.findViewById(R.id.row_group_aaa);
            		holder.buttonAccept = (ImageButton) convertView.findViewById(R.id.row_group_accept);
            		holder.buttonReject = (ImageButton) convertView.findViewById(R.id.row_group_reject);
            		holder.ll = (LinearLayout) convertView.findViewById(R.id.group_invitation);
            		
            		convertView.setTag(holder);
                }
                else  
    	        {  
    	            holder = (ViewHolder) convertView.getTag();  
    	        } 
                group = items.get(position);
                if (group != null) {

                		holder.buttonAccept.setOnClickListener(new View.OnClickListener() {
                			
                			final private int groupid = group.getIdOffline();
                			
                			public void onClick(View v) {

                				try {
									groupManager.acceptInvitation(groupid);
									//TODO: ??? is it necessary here - or after "acceptInvitation" will be async notice
	                			    
									reloadGroupList();
								} catch (ImposibleAcceptInvitation e) {
									Log.e("GROUP", "Imposible accept invitation.");
								}

                				
                				
                			}
                		});
                        
                		holder.buttonReject.setOnClickListener(new View.OnClickListener() {

                			final private int groupid = group.getIdOffline();
                			public void onClick(View v) {
                				
                				rejectInvitation(groupid);

                				//TODO: ??? is it necessary here - or after "rejectInvitation" will be async notice
                				reloadGroupList();
                			}
                		});
                        
                        if(group.getOwner() == userID){
                        	holder.image.setImageResource(R.drawable.ic_group_owner);
                        }
                        else{
                        	holder.image.setImageResource(R.drawable.ic_group_noowner);
                        }
                        
                        
                        if(holder.groupNameText != null) {
                        	holder.groupNameText.setText(group.getName());                            
                        }
                        if(holder.groupMembers != null){
                        	holder.groupMembers.setText("("+ String.valueOf(group.getUsers().size())+")");
                        }
                        if(isMember(group)){
                        	holder.ll.setVisibility(LinearLayout.GONE);
                        }
                        else{
                        	holder.ll.setVisibility(LinearLayout.VISIBLE);
                        }
                }
                
                convertView.setBackgroundColor(
                		getResources().getColor( (position%2 == 0)? R.color.list_element_even: R.color.list_element_odd )
                );
                return convertView;
        }
}
	
	
	private void rejectInvitation(int groupID){
		final int grID = groupID;
		AlertDialog.Builder builder = new AlertDialog.Builder(GroupListActivity.this);
		builder.setTitle(R.string.group_list_reject_invitation_title)
		.setMessage(R.string.group_list_reject_invitation_question)
		.setIcon(android.R.drawable.ic_menu_delete)
		.setCancelable(false)
	    .setPositiveButton(R.string.button_yes, new DialogInterface.OnClickListener() {
	           public void onClick(DialogInterface dialog, int id) {

   					groupManager.rejectInvitation(grID);
	               reloadGroupList();
	               dialog.cancel();
	           }
	       })
		.setNegativeButton(R.string.button_no, new DialogInterface.OnClickListener() {
	           public void onClick(DialogInterface dialog, int id) {
	               dialog.cancel();
	           }
	       });

		AlertDialog alert = builder.create();
		alert.show();
	}
	
	
	private boolean isMember(Group g){
		boolean result = false;
		for(int u: g.getUsers()){
			if(u == userID){
				result = true;
				break;
			}
		}
		return result;
	}


	private void reloadGroupList(){
		List<Group> list = groupManager.getGroupList();
	    if(list != null){
	    	groupList = new ArrayList<Group>(list);
	    	refreshAdapterList();
	    }
	}
	
	private void refreshAdapterList(){
		adapter.setNotifyOnChange(false);
		adapter.clear();
		for(Group gr: groupList){
			adapter.add(gr);
		}
		adapter.notifyDataSetChanged();
	}
	
	@Override
	public void asyncNotice(AsyncNoticeCode code) {
		switch(code){
			case GROUP_MANAGEMENT_ASYNC:
				reloadGroupList();
//				adapter.notifyDataSetChanged();
				break;
			case USERS_CHANGED:
				adapter.notifyDataSetChanged();
				break;
			case GROUPS_CHANGED:
				reloadGroupList();
//				adapter.notifyDataSetChanged();
				break;
			default:{
				
			}
		}	
		
	}

	@Override
	public Activity getActivity() {
		return this;
	}

	@Override
	public void syncStarted() {
		Log.d("ACTIONBAR", "Action bar refresh START!!!!!!!!!!!!");
		
		Intent action = new Intent();
		action.setAction("SYNC_STARTED");
		sendBroadcast(action);
	}

	@Override
	public void syncEnded() {
		Log.d("ACTIONBAR", "Action bar refresh END!!!!!!!!!!!!");
		
		Intent action = new Intent();
		action.setAction("SYNC_ENDED");
		sendBroadcast(action);
	}

	@Override
	public void syncAndWaitCallStarted() {
		showProgressDialog();
		
	}


	@Override
	public void syncAndWaitCallEnded(Object o, int syncAction) {
		hideProgressDialog();
		
	}
	
	
}
